use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::sync::Mutex;
use std::task::{Context, Poll, Waker};
use std::thread;
use std::time::Duration;
use tokio::join;
use tokio::macros::support::thread_rng_n;
use tokio::runtime::Runtime;
use tokio::time::sleep;

pub struct TimeFuture {
    shared_state: Arc<Mutex<SharedState>>,
}
struct SharedState {
    completed: bool,
    waker: Option<Waker>,
}

impl Future for TimeFuture {
    type Output = ();

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let mut state = self.shared_state.lock().unwrap();
        if state.completed {
            Poll::Ready(())
        } else {
            state.waker = Some(cx.waker().clone());
            Poll::Pending
        }
    }
}

impl TimeFuture {
    pub fn new(duration: Duration) -> Self {
        let shared_state = Arc::new(Mutex::new(SharedState {
            completed: false,
            waker: None,
        }));
        let thread_shared_state = shared_state.clone();
        thread::spawn(move || {
            thread::sleep(duration);
            let mut mutex_shared_state = thread_shared_state.lock().unwrap();
            mutex_shared_state.completed = true;
            if let Some(waker) = mutex_shared_state.waker.take() {
                waker.wake();
            }
        });

        Self { shared_state }
    }
}

